#include "inculde/model.h"
#include <cmath>

Model::Model(){
    this->weight = torch::randn({1,}, torch::requires_grad(true));
    this->bias = torch::randn({1,}, torch::requires_grad(true));
    this->loss = torch::empty({1,}, torch::requires_grad(true));
    std::cout << "init weight: \n" << weight << "\ninit bias: \n" << bias << std::endl;
};

torch::Tensor Model::forward(torch::Tensor input){
    predict = input * weight + bias;
    return predict;
};

int Model::backward(torch::Tensor true_value){
    float alpha = 0.01;
    loss = at::mse_loss(predict, true_value);
    auto out = loss.item<double>();
    if (out <= 0.003)
        return 1;
    else if(out <= 0.05)
        alpha *= 0.00000001;
    else if(out <= 0.1)
        alpha *= 0.000001;
    else if(out <= 0.5)
        alpha *= 0.0001;
    else if(out < 1)
        alpha *= 0.01;
    else if(out > 100){
        weight = torch::rand({1,}, torch::requires_grad(true));
        bias = torch::rand({1,}, torch::requires_grad(true));
        return 0;
    }

    loss.backward();

    weight.data() = weight.data() - alpha * weight.grad();
    bias.data() = bias.data() - alpha * bias.grad();

    return 0;
};

